001 package net.sf.xdc.util;
002
003 /*
004 * Copyright 2005-2006 Jens Voß.
005 *
006 * Licensed under the GNU Lesser General Public License (the "License");
007 * you may not use this file except in compliance with the License.
008 * You may obtain a copy of the License at
009 *
010 * http://opensource.org/licenses/lgpl-license.php
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018
019 import java.io.File;
020 import java.io.IOException;
021 import java.io.InputStream;
022 import java.io.OutputStream;
023 import java.io.Reader;
024 import java.io.Writer;
025 import java.io.FileReader;
026 import java.io.FileWriter;
027 import java.io.FileOutputStream;
028 import java.io.OutputStreamWriter;
029 import java.io.FileInputStream;
030 import java.io.InputStreamReader;
031 import java.io.FileNotFoundException;
032 import java.util.Collection;
033 import java.util.Arrays;
034 import java.nio.charset.Charset;
035
036 /**
037 * This utility class contains a number of useful static methods related to
038 * Stream manipulation.
039 *
040 * @author Jens Voß
041 * @since 0.5
042 * @version 0.5
043 */
044 public class IOUtils {
045
046 private static final int DEFAULT_BUFFER_SIZE = 4096;
047 private static final Collection DEFAULT_EXCLUDES = Arrays.asList(new String[] {
048 "CVS",
049 ".cvsignore",
050 "SCCS",
051 "vssver.scc",
052 ".svn",
053 ".DS_Store"
054 });
055
056
057 /**
058 * Reads byte data in chunks of a specified size from one stream and writes
059 * it into another stream.
060 *
061 * @param input The InputStream from which to read the data
062 * @param output The OutputStream to which to write the data
063 * @throws IOException
064 */
065 public static void copy(final InputStream input,
066 final OutputStream output)
067 throws IOException {
068 if (input == null) {
069 return;
070 }
071 final byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
072 int n;
073 while ((n = input.read(buffer)) != -1) {
074 output.write(buffer, 0, n);
075 }
076 }
077
078 /**
079 * Reads character data in chunks of a specified size from a Reader and
080 * writes it into a Writer.
081 *
082 * @param input The Reader from which to read the data
083 * @param output The Writer to which to write the data
084 * @throws IOException
085 */
086 public static void copy(final Reader input,
087 final Writer output) throws IOException {
088 if (input == null) {
089 return;
090 }
091 final char[] buffer = new char[DEFAULT_BUFFER_SIZE];
092 int n;
093 while ((n = input.read(buffer)) != -1) {
094 output.write(buffer, 0, n);
095 }
096 }
097
098 private static void copy(final File inFile, final File outFile)
099 throws IOException {
100 InputStream in = null;
101 OutputStream out = null;
102 try {
103 in = new FileInputStream(inFile);
104 out = new FileOutputStream(outFile);
105 copy(in, out);
106 }
107 finally {
108 if (in != null) {
109 in.close();
110 }
111 if (out != null) {
112 out.close();
113 }
114 }
115 }
116
117 /**
118 * This method is used to completely delete all contents of a directory
119 * including all files and (recursively) subdirectories, but not the
120 * (specified) directory itself.
121 *
122 * @param directory The directory whose contents are to be deleted
123 * @return <b>true</b> if the directory contains no more files after this
124 * operation; <b>false</b> otherwise (i.e. if some file could not be
125 * deleted for some reason)
126 */
127 public static boolean makeEmpty(File directory) {
128 File[] files = directory.listFiles();
129 if (files == null) {
130 return true;
131 }
132 boolean retVal = true;
133 for (int i = 0; i < files.length; i++) {
134 File file = files[i];
135 if (file.isDirectory()) {
136 retVal &= makeEmpty(file);
137 }
138 retVal &= file.delete();
139 }
140 return retVal;
141 }
142
143 /**
144 * This method is used to determine whether a path constituent should be
145 * excluded from processing because it is most likely a directory or file
146 * containing version control information.<br/>
147 * Excluded filename patterns are:
148 * <ul>
149 * <li>*~
150 * <li>#*#
151 * <li>.#*
152 * <li>%*%
153 * <li>._*
154 * <li>CVS
155 * <li>.cvsignore
156 * <li>SCCS
157 * <li>vssver.scc
158 * <li>.svn
159 * <li>.DS_Store
160 * </ul>
161 *
162 * @param filename The name of the path constituent (directory or file) for
163 * which a check is performed
164 * @return <b>true</b> if the filename matches one of the above patterns;
165 * <b>false</b> otherwise
166 */
167 public static boolean isDefaultExclude(String filename) {
168 return filename.endsWith("~")
169 || (filename.startsWith("#") && filename.endsWith("#"))
170 || filename.startsWith(".#")
171 || (filename.startsWith("%") && filename.endsWith("%"))
172 || filename.startsWith("._")
173 || DEFAULT_EXCLUDES.contains(filename);
174 }
175
176 /**
177 * This method is used to recursively copy the contents of one
178 * complete directory tree from one location in the file system
179 * to another.
180 *
181 * @param srcDir The source directory whose contents are to be
182 * copied
183 * @param targetDir The target directory (to which the contents
184 * of the source directory are copied)
185 * @throws IOException
186 */
187 public static void copyTree(File srcDir, File targetDir) throws IOException {
188 File[] files = srcDir.listFiles();
189 for (int i = 0; i < files.length; i++) {
190 File file = files[i];
191 File outFile = new File(targetDir, file.getName());
192 if (file.isFile()) {
193 copy(file, outFile);
194 }
195 else if (file.isDirectory()) {
196 outFile.mkdir();
197 copyTree(file, outFile);
198 }
199 }
200 }
201
202 /**
203 * This method constructs a <code>Reader</code> object of a <code>File</code>
204 * for a given <code>Charset</code>.
205 *
206 * @param file The file for which the <code>Reader</code> is to be
207 * constructed
208 * @param charset The <code>Charset</code> of the <code>Reader</code>
209 * to be constructed
210 * @return A <code>Reader</code> object for the specified <code>File</code>
211 * with the specified <code>Charset</code>
212 * @throws FileNotFoundException
213 */
214 public static Reader getReader(File file, Charset charset) throws FileNotFoundException {
215 if (charset != null) {
216 FileInputStream stream = new FileInputStream(file);
217 return new InputStreamReader(stream, charset);
218 }
219 else {
220 return new FileReader(file);
221 }
222 }
223
224 /**
225 * This method constructs a <code>Reader</code> object of a <code>File</code>
226 * for a given <code>Charset</code>.
227 *
228 * @param filename The name of the file for which the <code>Reader</code>
229 * is to be constructed
230 * @param charset The <code>Charset</code> of the <code>Reader</code>
231 * to be constructed
232 * @return A <code>Reader</code> object for the specified <code>File</code>
233 * with the specified <code>Charset</code>
234 * @throws FileNotFoundException
235 */
236 public static Reader getReader(String filename, Charset charset) throws FileNotFoundException {
237 if (charset != null) {
238 FileInputStream stream = new FileInputStream(filename);
239 return new InputStreamReader(stream, charset);
240 }
241 else {
242 return new FileReader(filename);
243 }
244 }
245
246 /**
247 * This method constructs a <code>Writer</code> object of a <code>File</code>
248 * for a given <code>Charset</code>.
249 *
250 * @param file The file for which the <code>Writer</code> is to be
251 * constructed
252 * @param charset The <code>Charset</code> of the <code>Writer</code>
253 * to be constructed
254 * @return A <code>Writer</code> object for the specified <code>File</code>
255 * with the specified <code>Charset</code>
256 * @throws FileNotFoundException
257 */
258 public static Writer getWriter(File file, Charset charset) throws IOException {
259 if (charset != null) {
260 FileOutputStream stream = new FileOutputStream(file);
261 return new OutputStreamWriter(stream, charset);
262 }
263 else {
264 return new FileWriter(file);
265 }
266 }
267
268 /**
269 * This method constructs a <code>Writer</code> object of a <code>File</code>
270 * for a given <code>Charset</code>.
271 *
272 * @param filename The name of the file for which the <code>Writer</code>
273 * is to be constructed
274 * @param charset The <code>Charset</code> of the <code>Writer</code>
275 * to be constructed
276 * @return A <code>Writer</code> object for the specified <code>File</code>
277 * with the specified <code>Charset</code>
278 * @throws FileNotFoundException
279 */
280 public static Writer getWriter(String filename, Charset charset) throws IOException {
281 if (charset != null) {
282 FileOutputStream stream = new FileOutputStream(filename);
283 return new OutputStreamWriter(stream, charset);
284 }
285 else {
286 return new FileWriter(filename);
287 }
288 }
289
290 private IOUtils() {
291 }
292
293 }